using UnityEngine;

[RequireComponent(typeof(PlayerView))]
[RequireComponent(typeof(CharacterInventory))]
[AddComponentMenu("Character/FPS Input Controller")]
[RequireComponent(typeof(CharacterMotor))]
public class FPSController : MonoBehaviour
{
	[HideInInspector]
	public CharacterSystem character;

	[HideInInspector]
	public CharacterMotor motor;

	[HideInInspector]
	public Vector3 inputDirection;

	private Vector2 mouseDirection;

	[HideInInspector]
	public PlayerView PlayerView;

	[HideInInspector]
	public float sensitivityXMult = 1f;

	[HideInInspector]
	public float sensitivityYMult = 1f;

	public float sensitivityX = 15f;

	public float sensitivityY = 15f;

	public float DampingSpeed = 300f;

	public float minimumX = -360f;

	public float maximumX = 360f;

	public float minimumY = -60f;

	public float maximumY = 60f;

	private float rotationX;

	private float rotationY;

	private float rotationXtemp;

	private float rotationYtemp;

	private Quaternion originalRotation;

	private Vector2 kickPower;

	private float fovTemp = 40f;

	private float fovTarget;

	private Vector3 aimPosition;

	[HideInInspector]
	public bool zooming;

	[HideInInspector]
	public CharacterDriver Driver;

	[HideInInspector]
	public CharacterSkyDriving SkyDrive;

	private float climbDirection;

	private void Start()
	{
		character = base.gameObject.GetComponent<CharacterSystem>();
		Driver = base.gameObject.GetComponent<CharacterDriver>();
		SkyDrive = base.gameObject.GetComponent<CharacterSkyDriving>();
		PlayerView = base.gameObject.GetComponent<PlayerView>();
		motor = GetComponent<CharacterMotor>();
		if ((bool)GetComponent<Rigidbody>())
		{
			GetComponent<Rigidbody>().freezeRotation = true;
		}
		originalRotation = base.transform.localRotation;
		if ((bool)PlayerView)
		{
			fovTemp = PlayerView.FPSCamera.MainCamera.fieldOfView;
			fovTarget = fovTemp;
		}
	}

	public void Zoom(float zoom)
	{
		fovTarget = zoom;
		zooming = !zooming;
	}

	public void Zoom(float zoom, Vector3 offset)
	{
		fovTarget = zoom;
		zooming = !zooming;
		aimPosition = offset;
		if (!zooming)
		{
			aimPosition = Vector3.zero;
		}
	}

	public void Kick(Vector2 power)
	{
		kickPower = power;
	}

	public void HideGun(bool visible)
	{
		if ((bool)PlayerView.FPSCamera.MainCamera)
		{
			PlayerView.FPSCamera.MainCamera.enabled = visible;
		}
	}

	public void Boost(float mult)
	{
		motor.boostMults = mult;
	}

	public void Climb(float speed)
	{
		motor.Climb(speed);
	}

	public void Drive(Vector2 axis, bool jump)
	{
		if ((bool)Driver)
		{
			Driver.Drive(axis, jump);
		}
	}

	public void OutVehicle()
	{
		if ((bool)SkyDrive)
		{
			SkyDrive.ReleaseParachute();
		}
		if ((bool)Driver)
		{
			Driver.OutVehicle();
		}
	}

	public void MoveCommand(Vector3 direction, bool jump)
	{
		if (Driver.DrivingSeat == null)
		{
			Move(direction);
			Jump(jump);
		}
		else
		{
			Drive(new Vector2(direction.x, direction.z), jump);
		}
	}

	public void Move(Vector3 directionVector)
	{
		if (character == null)
		{
			return;
		}
		inputDirection = directionVector;
		if (directionVector != Vector3.zero)
		{
			float magnitude = directionVector.magnitude;
			directionVector /= magnitude;
			magnitude = Mathf.Min(1f, magnitude);
			magnitude *= magnitude;
			directionVector *= magnitude;
			if (PlayerView.freeCamera != null && PlayerView.View == PlayerViewType.FreeView)
			{
				Quaternion rotation = Quaternion.LookRotation(PlayerView.freeCamera.transform.forward);
				Vector3 eulerAngles = rotation.eulerAngles;
				rotation.eulerAngles = new Vector3(0f, eulerAngles.y, 0f);
				Vector3 eulerAngles2 = rotation.eulerAngles;
				rotationXtemp = eulerAngles2.y;
				rotationX = rotationXtemp;
				base.transform.rotation = rotation;
			}
		}
		Quaternion rotation2 = base.transform.rotation;
		if ((bool)PlayerView.FPSCamera)
		{
			rotation2 = PlayerView.FPSCamera.transform.rotation;
		}
		Vector3 eulerAngles3 = rotation2.eulerAngles;
		eulerAngles3.x = 0f;
		eulerAngles3.z = 0f;
		rotation2.eulerAngles = eulerAngles3;
		character.MoveTo(rotation2 * directionVector);
	}

	public void Sprint(bool sprint)
	{
		character.Sprint = sprint;
	}

	public void Jump(bool jump)
	{
		motor.inputJump = jump;
		if (jump)
		{
			character.Jump();
		}
	}

	public void Aim(Vector2 direction)
	{
		if (PlayerView.View == PlayerViewType.FirstVeiw || PlayerView.View == PlayerViewType.ThirdView)
		{
			mouseDirection = direction;
		}
		else if ((bool)PlayerView && PlayerView.freeCamera != null && PlayerView.freeCamera.enabled)
		{
			PlayerView.freeCamera.Aim(direction);
			PlayerView.freeCamera.Target = base.gameObject;
		}
	}

	public void SwithView()
	{
		PlayerView.SwithView();
	}

	public void SwithSideView()
	{
		PlayerView.SwithViewSide();
	}

	public void Sit()
	{
		character.Sit();
	}

	public FPSItemEquipment FPSItem()
	{
		if (character == null)
		{
			return null;
		}
		if (character.inventory == null)
		{
			return null;
		}
		return character.inventory.FPSEquipment;
	}

	public void Trigger1(bool fire)
	{
		FPSItemEquipment fPSItemEquipment = FPSItem();
		if (!(fPSItemEquipment == null))
		{
			if (fire)
			{
				fPSItemEquipment.Trigger();
			}
			else
			{
				fPSItemEquipment.OnTriggerRelease();
			}
		}
	}

	public void Trigger2(bool fire)
	{
		FPSItemEquipment fPSItemEquipment = FPSItem();
		if (!(fPSItemEquipment == null))
		{
			if (fire)
			{
				fPSItemEquipment.Trigger2();
			}
			else
			{
				fPSItemEquipment.OnTrigger2Release();
			}
		}
	}

	public void Reload()
	{
		if (!(character == null))
		{
			character.Reload();
		}
	}

	public void Interactive()
	{
		if (!(character == null) && character.inventory != null)
		{
			character.Interactive(PlayerView.FPSCamera.RayPointer.position, PlayerView.FPSCamera.RayPointer.forward);
		}
	}

	public void Checking()
	{
		if (!(character == null))
		{
			character.Checking(PlayerView.FPSCamera.RayPointer.position, PlayerView.FPSCamera.RayPointer.forward);
		}
	}

	public void FixedRotation()
	{
		mouseDirection = Vector2.zero;
		rotationX = 0f;
		rotationXtemp = 0f;
		rotationY = 0f;
		rotationYtemp = 0f;
	}

	private void Update()
	{
		if ((MouseLock.MouseLocked || MouseLock.IsMobileControl) && !(character == null) && character.IsMine)
		{
			if (!zooming)
			{
				sensitivityXMult = 1f;
				sensitivityYMult = sensitivityXMult;
				fovTarget = fovTemp;
			}
			else
			{
				sensitivityXMult = fovTarget / fovTemp;
				sensitivityYMult = sensitivityXMult;
			}
			if ((bool)PlayerView.FPSCamera.MainCamera)
			{
				//PlayerView.FPSCamera.MainCamera.fieldOfView = Mathf.Lerp(PlayerView.FPSCamera.MainCamera.fieldOfView, fovTarget, 0.5f);
                PlayerView.FPSCamera.MainCamera.fieldOfView = Mathf.Lerp(PlayerView.FPSCamera.MainCamera.fieldOfView, 40f, 0.5f);
            }
			if ((bool)PlayerView)
			{
				PlayerView.FPSCamera.aimOffset = aimPosition;
				PlayerView.FPSCamera.zooming = zooming;
			}
			motor.boostMults += (1f - motor.boostMults) * Time.deltaTime;
			kickPower.y += (0f - kickPower.y) / 20f;
			kickPower.x += (0f - kickPower.x) / 20f;
			rotationXtemp += mouseDirection.x * sensitivityX * sensitivityXMult;
			rotationYtemp += mouseDirection.y * sensitivityY * sensitivityYMult;
			rotationX = Mathf.Lerp(rotationX, rotationXtemp, DampingSpeed * Time.deltaTime);
			rotationY = Mathf.Lerp(rotationY, rotationYtemp, DampingSpeed * Time.deltaTime);
			if (rotationX >= 360f)
			{
				rotationX = 0f;
				rotationXtemp = 0f;
			}
			if (rotationX <= -360f)
			{
				rotationX = 0f;
				rotationXtemp = 0f;
			}
			if (character.MovementPreset.Length > character.MovementIndex)
			{
				maximumY = character.MovementPreset[character.MovementIndex].FPSCameraMaxY;
				minimumY = character.MovementPreset[character.MovementIndex].FPSCameraMinY;
			}
			rotationX = ClampAngle(rotationX, minimumX, maximumX);
			rotationY = ClampAngle(rotationY, minimumY, maximumY);
			rotationYtemp = ClampAngle(rotationYtemp, minimumY, maximumY);
			Quaternion rhs = Quaternion.AngleAxis(rotationX + kickPower.x, Vector3.up);
			Quaternion rhs2 = Quaternion.AngleAxis(rotationY + kickPower.y, Vector3.left);
			if ((bool)PlayerView.FPSCamera)
			{
				PlayerView.FPSCamera.transform.localRotation = originalRotation * Quaternion.AngleAxis(0f, -Vector3.up) * rhs2;
				base.transform.localRotation = originalRotation * rhs * Quaternion.AngleAxis(0f, Vector3.left);
			}
			else
			{
				base.transform.localRotation = originalRotation * rhs * rhs2;
			}
		}
	}

	public void Stun(float val)
	{
		kickPower.y = val;
	}

	private static float ClampAngle(float angle, float min, float max)
	{
		if (angle < -360f)
		{
			angle += 360f;
		}
		if (angle > 360f)
		{
			angle -= 360f;
		}
		return Mathf.Clamp(angle, min, max);
	}
}
